from rest_framework import serializers
from django.contrib.auth.models import User
from .models import Genre, Movie, Rating, Comment


class UserSerializer(serializers.ModelSerializer):
    """用户序列化器"""
    password = serializers.CharField(write_only=True)
    
    class Meta:
        model = User
        fields = ('id', 'username', 'email', 'first_name', 'last_name', 'password', 'is_staff', 'is_active')
    
    def create(self, validated_data):
        password = validated_data.pop('password')
        user = User.objects.create_user(**validated_data)
        user.set_password(password)
        user.save()
        return user


class GenreSerializer(serializers.ModelSerializer):
    """电影类型序列化器"""
    
    class Meta:
        model = Genre
        fields = ('id', 'name')


class MovieSerializer(serializers.ModelSerializer):
    """电影序列化器"""
    genres = GenreSerializer(many=True, read_only=True)
    genre_ids = serializers.ListField(
        child=serializers.IntegerField(),
        write_only=True,
        required=False
    )
    average_rating = serializers.SerializerMethodField()
    user_rating = serializers.SerializerMethodField()
    poster = serializers.ImageField(required=False, allow_null=True)
    
    class Meta:
        model = Movie
        fields = ('id', 'movie_id', 'title', 'year', 'director', 'description', 'poster', 'genres', 'genre_ids', 'average_rating', 'user_rating')
    
    def get_average_rating(self, obj):
        ratings = obj.rating_set.all()
        if ratings:
            return round(sum(r.rating for r in ratings) / len(ratings), 2)
        return 0
    
    def get_user_rating(self, obj):
        request = self.context.get('request')
        if request and request.user.is_authenticated:
            try:
                rating = obj.rating_set.get(user=request.user)
                return rating.rating
            except Rating.DoesNotExist:
                return None
        return None
    
    def validate_movie_id(self, value):
        # 检查movie_id是否已存在
        queryset = Movie.objects.filter(movie_id=value)
        if self.instance:
            # 更新时排除当前实例
            queryset = queryset.exclude(pk=self.instance.pk)
        if queryset.exists():
            raise serializers.ValidationError("具有此电影ID的电影已存在。")
        return value
    
    def create(self, validated_data):
        genre_ids = validated_data.pop('genre_ids', [])
        movie = Movie.objects.create(**validated_data)
        if genre_ids:
            movie.genres.set(genre_ids)
        return movie
    
    def update(self, instance, validated_data):
        genre_ids = validated_data.pop('genre_ids', None)
        for attr, value in validated_data.items():
            setattr(instance, attr, value)
        instance.save()
        if genre_ids is not None:
            instance.genres.set(genre_ids)
        return instance


class RatingSerializer(serializers.ModelSerializer):
    """评分序列化器"""
    movie_title = serializers.CharField(source='movie.title', read_only=True)
    user_name = serializers.CharField(source='user.username', read_only=True)
    
    class Meta:
        model = Rating
        fields = ('id', 'user', 'movie', 'rating', 'timestamp', 'movie_title', 'user_name')
        read_only_fields = ('user', 'timestamp')
        
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 如果是更新操作，将movie字段设置为只读
        if self.instance:
            self.fields['movie'].read_only = True
        
    def validate(self, data):
        """验证用户是否已经对该电影评分"""
        user = self.context['request'].user
        
        # 如果是更新操作，直接返回数据，不需要检查重复
        if self.instance:
            return data
        
        # 创建操作需要检查重复和movie字段
        if 'movie' not in data:
            raise serializers.ValidationError("创建评分时必须提供电影信息。")
            
        movie = data['movie']
        existing_rating = Rating.objects.filter(
            user=user, movie=movie
        ).first()
            
        if existing_rating:
            raise serializers.ValidationError(
                "您已经对这部电影评过分了，请更新现有评分。"
            )
            
        return data


class CommentSerializer(serializers.ModelSerializer):
    """留言序列化器"""
    user_name = serializers.CharField(source='user.username', read_only=True)
    movie_title = serializers.CharField(source='movie.title', read_only=True)
    
    class Meta:
        model = Comment
        fields = ('id', 'user', 'movie', 'content', 'timestamp', 'user_name', 'movie_title')
        read_only_fields = ('user', 'movie', 'timestamp')
    
    def validate_content(self, value):
        """验证留言内容"""
        if len(value.strip()) < 5:
            raise serializers.ValidationError("留言内容至少需要5个字符。")
        if len(value) > 1000:
            raise serializers.ValidationError("留言内容不能超过1000个字符。")
        return value.strip()


class MovieRecommendationSerializer(serializers.Serializer):
    """电影推荐序列化器"""
    movie = MovieSerializer()
    predicted_rating = serializers.FloatField()
    similarity_score = serializers.FloatField()